import 'dart:math';
import 'package:flutter/material.dart';

class ProgressManager extends StatefulWidget {
  List<Color> colors;
  ProgressManager(  List<Color> colors){
    this.colors=colors;
  }
  @override
  _ProgressManagerState createState() =>
      new _ProgressManagerState().._factory = WavePainterFactory(colors);
}

class _ProgressManagerState extends State<ProgressManager>
    with TickerProviderStateMixin {
  AnimationController xController;
  AnimationController yController;
  Animation<double> xAnimation;
  Animation<double> yAnimation;
  List<double> _progressList = [];
  double curProgress = 0;
  BasePainterFactory _factory;

  set painter(BasePainterFactory factory) {
    _factory = factory;
  }
  setProgress(double progress) {
    _progressList.add(progress);
    onProgressChange();
  }

  onProgressChange() {
    if (_progressList.length > 0) {
      if (yController != null && yController.isAnimating) {
        return;
      }
      double nextProgress = _progressList[0];
      _progressList.removeAt(0);
      final double begin = curProgress;
      yController = new AnimationController(
          vsync: this, duration: Duration(milliseconds: 1000));
      yAnimation =
          new Tween(begin: begin, end: nextProgress).animate(yController);
      yAnimation.addListener(_onProgressChange);
      yAnimation.addStatusListener(_onProgressStatusChange);
      yController.forward();
    }
  }

  @override
  void initState() {
    super.initState();
    xController = new AnimationController(
        vsync: this, duration: Duration(milliseconds: 4000));
    xAnimation = new Tween(begin: 0.0, end: 1.0).animate(xController);
    xAnimation.addListener(_change);
    yController = new AnimationController(
        vsync: this, duration: Duration(milliseconds: 5000));
    yAnimation = new Tween(begin: 0.0, end: 1.0).animate(yController);
    yAnimation.addListener(_onProgressChange);
    yAnimation.addStatusListener(_onProgressStatusChange);
    doDelay(xController, 0);
    Future.delayed(Duration(milliseconds: 3000), () {
      setProgress(1);
    });
  }

  @override
  Widget build(BuildContext context) {
    return
      Container(
        width: MediaQuery.of(context).size.width,
        height: 100.0,
        child: new CustomPaint(
//        size: Size(200,100),
          painter: _factory.getPainter()
            ..XAnimation = xAnimation
            ..YAnimation = yAnimation,
        size: new Size(MediaQuery.of(context).size.width, 100.0),
        ),
      );
  }

  void _change() {
    setState(() {});
  }

  void _onProgressChange() {
    setState(() {
      curProgress = yAnimation.value;
    });
  }

  void _onProgressStatusChange(status) {
    if (status == AnimationStatus.completed) {
      onProgressChange();
    }
  }

  void doDelay(AnimationController controller, int delay) async {
    Future.delayed(Duration(milliseconds: delay), () {
      controller..repeat();
    });
  }

  @override
  void dispose() {
    xController.dispose();
    yController.dispose();
    xAnimation.removeListener(_change);
    yAnimation.removeListener(_onProgressChange);
    yAnimation.removeStatusListener(_onProgressStatusChange);
    super.dispose();
  }
}
/**
 * 获取绘制器
 */
abstract class BasePainterFactory {
  BasePainter getPainter();
}
/**
 * 创建绘制器
 */
class WavePainterFactory extends BasePainterFactory {
  List<Color> colors;
  WavePainterFactory(  List<Color> colors){

this.colors=colors;
print(colors.toString());
  }
  BasePainter getPainter() {
    return WavePainter(
      waveCount: 1,
      waveColors:colors,
    );
  }
}









//https://blog.csdn.net/u010758352/article/details/89537267
/**
 * 1..创建绘制波浪边界的代码
  创建一个基础的绘制类，可接收动画的x和y值：
    获取画笔
 */

abstract class BasePainter extends CustomPainter{
  Animation<double> _xAnimation;
  Animation<double> _yAnimation;

  set XAnimation(Animation<double> value) {
    _xAnimation = value;
  }

  set YAnimation(Animation<double> value) {
    _yAnimation = value;
  }

  Animation<double> get YAnimation => _yAnimation;

  Animation<double> get XAnimation => _xAnimation;

}

/**
 * 画笔绘制
 * 绘制具
 * 体实现
 */
class WavePainter extends BasePainter {
  /**
   * 水波个数
   */
  int waveCount;

  /**
   * 波峰个数
   */
  int crestCount;
  /**
   * 波纹高度
   */
  double waveHeight;
  /**
   * 波纹颜色
   */
  List<Color> waveColors;

  WavePainter(
      {this.waveCount = 1,
        this.crestCount = 2,
        this.waveHeight=10,
        this.waveColors,
    });

  @override
  void paint(Canvas canvas, Size size) {
    double width = size.width;
    double height = size.height;
  //未设置波高进行初始化
    if (waveHeight == null) {
      waveHeight = height / 10;
      height = height + waveHeight;
    }
    //未设置颜色进行初始化
    if (waveColors == null) {
      waveColors = [
        Color.fromARGB( 100, Colors.blue.red, Colors.blue.green, Colors.blue.blue)
      ];
    }

    //中心点
    Offset center = new Offset(width / 2, height / 2);
    //x起始点当前动画起始位置
    double xMove = width * XAnimation.value;
    //y轴位子
    double yAnimValue = 0.0;

    if (YAnimation != null) {
      yAnimValue = YAnimation.value;
    }

    //y移动
    double yMove = height * (1.0 - yAnimValue);

    Offset waveCenter = new Offset(xMove, yMove);
    /**
     * 水波绘制
     */
    List<Path> wavePaths = [];
    //计算位置
    for (int index = 0; index < waveCount; index++) {
      double direction = pow(-1.0, index);
      Path path = new Path()
        ..moveTo(waveCenter.dx - width, waveCenter.dy)
        ..lineTo(waveCenter.dx - width, center.dy + height / 2)
        ..lineTo(waveCenter.dx + width, center.dy + height / 2)
        ..lineTo(waveCenter.dx + width, waveCenter.dy);
      for (int i = 0; i < 2; i++) {
        for (int j = 0; j < crestCount; j++) {
          double a = pow(-1.0, j);
          path
            ..quadraticBezierTo(
                waveCenter.dx +
                    width * (1 - i - (1 + 2 * j) / (2 * crestCount)),
                waveCenter.dy + waveHeight * a * direction,
                waveCenter.dx +
                    width * (1 - i - (2 + 2 * j) / (2 * crestCount)),
                waveCenter.dy);
        }
      }
      path..close();
      wavePaths.add(path);
    }
//    画笔初始化
    var paint = new Paint()
      ..style = PaintingStyle.fill
      ..maskFilter = MaskFilter.blur(BlurStyle.inner, 5.0);
    //进行绘制（）
    canvas.saveLayer(  Rect.fromCircle(center: center, radius: min(width, height) / 2), paint);
      paint
      ..style = PaintingStyle.fill
      ..strokeWidth = 2.0
      ..maskFilter = MaskFilter.blur(BlurStyle.inner, 10.0);
//进行绘制
    for (int i = 0; i < wavePaths.length; i++) {
      if (waveColors.length >= wavePaths.length) {
        paint.color = waveColors[i];
      } else {
        paint.color = waveColors[0];
      }
      canvas.drawPath(wavePaths[i], paint);
    }

    canvas.restore();
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return oldDelegate != this;
  }
}